import java.util.*;

class Test{

	public static void main(String []args){
		new Test();
	}

	public Test(){
		run();
	}
	
	// generator with the system-time as a seed
	private Random generator = new Random(System.currentTimeMillis());

	private int raupenPerFactory;
	private int schwenkPerFactory;
	private int lackierPerFactory;
	private int schweisPerFactory;
	
	private int raupenGesamt;
	private int schwenkGesamt;
	private int lackierGesamt;
	private int schweisGesamt;
	
	private int betriebsstundenSchweis;
	private int betriebsstundenLackier;
	private int betriebsstundenRaupe;
	private int betriebsstundenSchwenk;
	
	private int rotationenSchweis;
	private int rotationenLakier;
	
	private int raupenSchweis;
	private int raupenLakier;
	
	private int mintempSchweis;
	private int maxtempSchweis;
	
	private int raupenSchweisGesamt;
	private int raupenLakierGesamt;
	
	private void resetStatistics(boolean global){
		raupenPerFactory = 0; //
		schwenkPerFactory = 0; //
		lackierPerFactory = 0; //
		schweisPerFactory = 0; //
		
		if(global){
			raupenGesamt = 0;
			schwenkGesamt = 0;
			lackierGesamt = 0;
			schweisGesamt = 0;
		}
		
		betriebsstundenSchweis = 0; //
		betriebsstundenLackier = 0; //
		betriebsstundenRaupe = 0; // 
		betriebsstundenSchwenk = 0; //
		
		rotationenSchweis = 0;
		rotationenLakier = 0;
		
		raupenSchweis = 0;
		raupenLakier = 0;
		
		if(global){
			
			mintempSchweis = -1; //
			maxtempSchweis = 0; //
			
			raupenSchweisGesamt = 0;
			raupenLakierGesamt = 0;
		}
	}

	// returns a random int a, where from <= a <= to
	private int rand(int from, int to){
		return from + generator.nextInt(to+1);
	}

	// creates and returns a random configured robot
	private Roboter createRandomRobot(){

		Roboter robot;
		RoboterRole role;
		
		int hoursOperational = rand(0, 100);
		
		boolean schwenk = (rand(0, 1) == 1) ? true : false;
		boolean schweis = (rand(0, 1) == 1) ? true : false;
		
		// generate random robot
		if(schwenk){
			robot = Roboter.createRoboter(Roboter.Type.SCHWENKARMROBOTER);
			robot.setValue(rand(0, 12000)); // set the number of rotations
			schwenkPerFactory++;
			betriebsstundenSchwenk += hoursOperational;
		}
		else {
			robot = Roboter.createRoboter(Roboter.Type.RAUPENROBOTER);
			robot.setValue(rand(0, 1000)); // distance covered
			raupenPerFactory++;
			betriebsstundenRaupe += hoursOperational;
		}

		// give him a random tool
		if(schweis){
			role = Roboter.createRoboterRole(Roboter.Role.SCHWEISROBOTER);
			role.setValue(rand(300, 1300)); // welding-temperature
			
			if(role.getValue() < mintempSchweis || mintempSchweis == -1)
				mintempSchweis = (int) role.getValue();
				
			if(role.getValue() > maxtempSchweis)
				maxtempSchweis = (int) role.getValue();
				
			schweisPerFactory++;
			betriebsstundenSchweis += hoursOperational;
		}
		else {
			role = Roboter.createRoboterRole(Roboter.Role.LACKIERROBOTER);
			role.setValue(rand(1, 50)); // set capacity
			lackierPerFactory++;
			betriebsstundenLackier += hoursOperational;
		}
		
		if(schwenk){
			if(schweis)
				rotationenSchweis += robot.getValue();
			else
				rotationenLakier += robot.getValue();
		} else {
			// raupenroboter
			if(schweis)
				raupenSchweis++;
			else
				raupenLakier++;
		}
		
		robot.setRoboterRole(role);
		
		robot.increaseOperatingHours(hoursOperational);
		
		return robot;
	}


	// fill factories with a random number of robots between from and to
	private void fillFactories(int from, int to){

		resetStatistics(true);
		int fabrikCount = 0;
		Fabrik f;
		while((f = Fabrik.getFabric("Fabrik "+fabrikCount)) != null){
			System.out.println("-----------------------------------------------");
			System.out.println("Filling factory "+f+"...");

			int noOfRoboters = rand(from, to);

			for(int i = 0; i < noOfRoboters; i++){
				Roboter r = createRandomRobot();
				f.addRoboter(r);
				System.out.println("added robot "+r);
			}
			
			System.out.println("total number of robots: "+(raupenPerFactory+schwenkPerFactory));
			System.out.println("raupen: "+raupenPerFactory+"; schwenk: "+schwenkPerFactory+";");
			System.out.println("schweis: "+schweisPerFactory+"; lackier: "+lackierPerFactory);
			System.out.println("raupen: "+raupenLakier+" mal lackier; "+raupenSchweis+" mal schweis;");
			System.out.println("rotationenSchweis: "+rotationenSchweis+"; rotationenLackier: "+rotationenLakier);
			System.out.println("mintempSchweis: "+mintempSchweis+"; maxtempSchweis: "+maxtempSchweis);
			System.out.println("betriebsstunden: ");
			System.out.println("raupen: "+betriebsstundenRaupe+"; schwenk: "+betriebsstundenSchwenk);
			System.out.println("lackier: "+betriebsstundenLackier+"; schweis: "+betriebsstundenSchweis);
			System.out.println("-----------------------------------------------");
			
			raupenGesamt += raupenPerFactory;
			schweisGesamt += schweisPerFactory;
			schwenkGesamt += schwenkPerFactory;
			lackierGesamt += lackierPerFactory;
			
			raupenSchweisGesamt += raupenSchweis;
			raupenLakierGesamt += raupenLakier;
			
			resetStatistics(false);
			
			fabrikCount++;
		}
		
		System.out.println("-----------------------------------------------");
		System.out.println("overall statistics: ");
		System.out.println("schweis: "+schweisGesamt+" lackier: "+lackierGesamt);
		System.out.println("raupen: "+raupenGesamt+" schwenk: "+schwenkGesamt);
		System.out.println("raupenschweis: "+raupenSchweisGesamt+" raupenlackier: "+raupenLakierGesamt);
		System.out.println("-----------------------------------------------");
	
	}
	
	// testing the Fabrik-factory
	private void testFactoryFactory(){
		Fabrik f = Fabrik.createFabric("A");
		if(f == null) {
			System.out.println("no fabric");
		} else {
			System.out.println(f.NAME);
		}
		f = Fabrik.createFabric("A");
		if(f == null) {
			System.out.println("no fabric");
		} else {
			System.out.println(f.NAME);
		}
		f = Fabrik.createFabric("B");
		if(f == null) {
			System.out.println("no fabric");
		} else {
			System.out.println(f.NAME);
		}
		f = Fabrik.createFabric("C");
		if(f == null) {
			System.out.println("no fabric");
		} else {
			System.out.println(f.NAME);
		}
	}

	
	private void testStatistics(int size){
		// creat a bunch of factories
		System.out.println("creating "+size+" factories...");
		for(int i = 0; i < size; i++){
			Fabrik.createFabric("Fabrik "+i);
		}
		System.out.println("created!");

		// fill the factories with robots
		System.out.println("fill factories with a random number of robots (between 0 and 3)");
		fillFactories(0, 3);
		System.out.println("filled!");

		// print statistics
		System.out.println("getting statistics:");
		int fabrikCount = 0;
		Fabrik f;
		while((f = Fabrik.getFabric("Fabrik "+fabrikCount)) != null) {
			System.out.println("Factory "+f+":");
			System.out.println("average hours: "+f.getAverageHours());
			System.out.println("average hours per roboter type: "+f.getAverageHoursPerRoboterType());
			System.out.println("average rotations: "+f.getAverageRotations());
			System.out.println("average distance"+f.getAverageDistance());
			fabrikCount++;
		}
		
		// statistics of all factories
		System.out.println("overall statistics: ");
		System.out.println("average distance: "+Fabrik.getAverageDistanceAllFabrics());
		System.out.println("min max temperature: "+Fabrik.getMinMaxOperatingTemperature());
	}
	
	private void testRemoveRobot(){
		System.out.println("create a factory and add 2 robots");
		Fabrik f = Fabrik.createFabric("removetest");
		Roboter r1 = createRandomRobot();
		Roboter r2 = createRandomRobot();
		f.addRoboter(r1);
		f.addRoboter(r2);
		System.out.println("average rotatiosn: "+f.getAverageRotations());
		System.out.println("average distance: "+f.getAverageDistance());
		System.out.println("remove robot "+r1);
		f.removeRoboter(r1.ID);
		System.out.println("average rotatiosn: "+f.getAverageRotations());
		System.out.println("average distance: "+f.getAverageDistance());
	}
	
	private void run(){

		System.out.println("--------------------");
		System.out.println("Testing factories...");
		testFactoryFactory();
		System.out.println("--------------------");
	
		System.out.println("--------------------");
		System.out.println("Testing statistics...");
		testStatistics(1);
		System.out.println("--------------------");
		
		System.out.println("--------------------");
		System.out.println("Testing remove robot...");
		testRemoveRobot();
		System.out.println("--------------------");

	}

}



